package me.magicall.db.dao2;

import java.util.Collection;
import java.util.List;

import me.magicall.coll.CollFactory;
import me.magicall.db.Condition;
import me.magicall.db.dao.CommonDao;
import me.magicall.db.util.DbUtil;
import me.magicall.db.util.PageInfo;
import me.magicall.db.util.ReturnKeyAndAffect;
import me.magicall.util.kit.Kits;

public abstract class AbsDaoImpl<T> implements Dao2<T> {

	protected CommonDao<T> commonDao;

	protected AbsDaoImpl() {
		super();
	}

	public AbsDaoImpl(final CommonDao<T> commonDao) {
		this.commonDao = commonDao;
	}

	@Override
	public List<T> all() {
		return list(new Query<T>());
	}

	@Override
	public T getById(final Object id) {
		return getById(id, new Query<T>());
	}

	@Override
	public T getById(final Object id, final Query<T> query) {
		query.addConditions(new Condition(idFieldName(), id));
		return getOne(query);
	}

	@Override
	public T getOne(final Query<T> query) {
		query.setPageInfo(PageInfo.FIRST_ONE);
		final List<T> list = list(query);
		return Kits.COLL.isEmpty(list) ? null : list.get(0);
	}

	@Override
	public int countAll() {
		return count(new Query<T>());
	}

	@Override
	public int delById(final Object... id) {
		return delById(CollFactory.L.asList(id));
	}

	public T fill(final T modelWithId) {
		return commonDao.fill(modelWithId);
	}

	public Collection<T> fill(final T... modelWithId) {
		return commonDao.fill(modelWithId);
	}

	public Collection<T> fill(final Collection<T> modelsWithId) {
		return commonDao.fill(modelsWithId);
	}

	public ReturnKeyAndAffect addReturnKey(final T model) {
		return commonDao.addReturnKey(model);
	}

	public ReturnKeyAndAffect addReturnKey(final T... models) {
		return commonDao.addReturnKey(models);
	}

	public ReturnKeyAndAffect addReturnKey(final Collection<? extends T> models) {
		return commonDao.addReturnKey(models);
	}

	public int addIfAbsent(final T... models) {
		return commonDao.addIfAbsent(models);
	}

	public int addIfAbsent(final Collection<? extends T> models) {
		return commonDao.addIfAbsent(models);
	}

	public boolean add(final T model) {
		return commonDao.add(model);
	}

	public int[] add(final T... models) {
		return commonDao.add(models);
	}

	public int[] add(final Collection<? extends T> models) {
		return commonDao.add(models);
	}

	public int update(final T model) {
		return commonDao.update(model);
	}

	public int[] update(final T... models) {
		return commonDao.update(models);
	}

	public int[] update(final Collection<? extends T> models) {
		return commonDao.update(models);
	}

	public boolean addOrUpdate(final T model) {
		return commonDao.addOrUpdate(model);
	}

	public int[] addOrUpdate(final T... models) {
		return commonDao.addOrUpdate(models);
	}

	public int[] addOrUpdate(final Collection<? extends T> models) {
		return commonDao.addOrUpdate(models);
	}

	public int del(final T model) {
		return commonDao.del(model);
	}

	public int[] del(final Collection<? extends T> models) {
		return commonDao.del(models);
	}

	public int[] del(final T... models) {
		return commonDao.del(models);
	}

	protected String idFieldName() {
		return DbUtil.COMMON_ID_FIELD_NAME;
	}

	protected String idColumnName() {
		return DbUtil.COMMON_ID_COLUMN_NAME;
	}

	protected String modelClassName(final Class<?> clazz) {
		return clazz.getSimpleName();
	}

	protected CommonDao<T> getCommonDao() {
		return commonDao;
	}

	protected void setCommonDao(final CommonDao<T> commonDao) {
		this.commonDao = commonDao;
	}

	@Override
	public int delById(final Collection<? extends Object> id) {
		final Query<T> query = new Query<T>();
		query.setConditions(new Condition(idFieldName(), id));
		return del(query);
	}

}